"""
自定义日志输出格式
日志记录的步骤：
   ① 创建logger
   ②  创建handler
   ③ 定义formatter
   ④ 给handler添加formatter
   ⑤ 给logger添加handler
"""
import os
import logging
from flask import request
from logging import handlers


# 定义一个日志格式化类
class RequestShoppingFormat(logging.Formatter):
    def format(self, record):
        """
        格式化日志输出
        :param record:
        :return:
        """
        # 记录请求的url
        record.url = request.url
        # 记录请求的ip地址
        record.remote_addr = request.remote_addr
        # 返回格式化输出
        return super().format(record)


def create_logger(app):
    """
    自定义日志
    :param app:
    :return:
    """
    # 日志的级别
    logging_level = app.config['LOGGING_LEVEL']
    # 日志存放位置
    logging_file_dir = app.config['LOGGING_FILE_DIR']
    # 日志大小
    logging_file_max_bytes = app.config['LOGGING_FILE_MAX_BYTES']
    # 备份日志的个数
    logging_file_backup = app.config['LOGGING_FILE_BACKUP']

    # 日志的输出格式[针对文件]
    """
    asctime:时间，精确到秒
    remote_addr:请求的地址
    url:请求的url
    levelname:日志级别
    module:文件名
    lineno:行号
    message:信息
    s:字符串
    d:数字
    """
    # 日志输出的格式
    request_format = RequestShoppingFormat(
        '[%(asctime)s] %(remote_addr)s 请求 %(url)s \t %(levelname)s 在%(module)s %(lineno)d: %(message)s')
    # 判断存放日志的目录是否存在
    if os.path.isdir(logging_file_dir):
        pass
    else:
        os.mkdir(logging_file_dir)
    # 日志的目标 自定义文件输出的目录  创建一个输出到文件里的handler
    flask_file_handler = logging.handlers.RotatingFileHandler(filename=os.path.join(logging_file_dir, 'shopping.log'),
                                                              maxBytes=logging_file_max_bytes,
                                                              backupCount=logging_file_backup, encoding='utf-8')
    # 添加日志的输出格式到日志中去 给写入文件的handler添加format
    flask_file_handler.setFormatter(request_format)

    # 创建一个logger对象
    # 注意：getLogger里面的参数需要和被调用的文件名一致，否则日志无法输出到文件中 在加载到app中，和app所在的父级文件夹名一致
    flask_logger = logging.getLogger('shopping')
    # 给logger添加一个handler对象
    flask_logger.addHandler(flask_file_handler)
    # 设置日志的等级
    flask_logger.setLevel(logging_level)

    # 整个项目需要两个日志，一个输出在控制台，一个输出在文件
    # logging.StreamHandler() 默认的日志对象
    flask_conslole_logger = logging.StreamHandler()
    # 给输出到控制台的日志添加格式
    flask_conslole_logger.setFormatter(
        logging.Formatter('[%(asctime)s] %(levelname)s 在%(module)s %(lineno)d: %(message)s'))

    # 如果当前环境是debug模式，则在终端打印日志
    if app.debug:
        flask_logger.addHandler(flask_conslole_logger)